package org.traffometer.traffobase.model;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import org.junit.Test;
import org.traffometer.common.data.TraffoPacket;
import org.traffometer.opendmtp.protocol.GeoPoint;

/**
 * Tests SerializedPacketStore.
 * @author Mark Stillwell
 */
public class TestFilePacketStore extends TestCase {

  private static final String packetFileRelativePath = "tmp/packets.txt";
  
  /**
   * Compares the contents of two Iterable TraffoPackets.
   * @param iter1 the first iterable
   * @param iter2 the second iterable
   * @return true if the contents are the same
   */
  private boolean equalContents(Iterable<TraffoPacket> iter1, Iterable<TraffoPacket> iter2) {
    List<Double> iter1lat1  = new ArrayList<Double>();
    List<Double> iter1long1 = new ArrayList<Double>();
    List<Long>   iter1time1 = new ArrayList<Long>();
    List<Double> iter1lat2  = new ArrayList<Double>();
    List<Double> iter1long2 = new ArrayList<Double>();
    List<Long>   iter1time2 = new ArrayList<Long>();
    List<String> iter1veh   = new ArrayList<String>();
    List<Double> iter2lat1  = new ArrayList<Double>();
    List<Double> iter2long1 = new ArrayList<Double>();
    List<Long>   iter2time1 = new ArrayList<Long>();
    List<Double> iter2lat2  = new ArrayList<Double>();
    List<Double> iter2long2 = new ArrayList<Double>();
    List<Long>   iter2time2 = new ArrayList<Long>();
    List<String> iter2veh   = new ArrayList<String>();

    for (TraffoPacket packet : iter1) {
      iter1lat1.add(packet.getLatitude1());
      iter1long1.add(packet.getLongitude1());
      iter1time1.add(packet.getTimeStamp1());
      iter1lat2.add(packet.getLatitude2());
      iter1long2.add(packet.getLongitude2());
      iter1time2.add(packet.getTimeStamp2());
      iter1veh.add(packet.getVehicleType());
    }
    for (TraffoPacket packet : iter2) {
      iter2lat1.add(packet.getLatitude1());
      iter2long1.add(packet.getLongitude1());
      iter2time1.add(packet.getTimeStamp1());
      iter2lat2.add(packet.getLatitude2());
      iter2long2.add(packet.getLongitude2());
      iter2time2.add(packet.getTimeStamp2());
      iter2veh.add(packet.getVehicleType());
    }
    
    boolean retVal = iter1lat1.equals(iter2lat1) && iter1long1.equals(iter2long1);
    retVal = retVal && iter1time1.equals(iter2time1) && iter1lat2.equals(iter2lat2);
    retVal = retVal && iter1long2.equals(iter2long2) && iter1time2.equals(iter2time2);
    retVal = retVal && iter1veh.equals(iter2veh);
    return retVal;
  }
  
  /**
   * Tests FilePacketStore.
   * @throws Exception if there are problems
   */
  @Test
  public void testSerializedPacketStore() throws Exception {
    File packetFile = new File(packetFileRelativePath);
    File packetFileParent = new File(packetFile.getParent());
    String packetFilePath = packetFile.getCanonicalPath();
    if (packetFile.isFile()) {
      packetFile.delete();
    }
    else {
      if (!packetFileParent.isDirectory()) {
        packetFileParent.mkdir();
      }
    }
    PacketStore packetStore = new FilePacketStore(packetFilePath);
    List<TraffoPacket> packetList = new ArrayList<TraffoPacket>();    
    TraffoPacket packet = 
        new TraffoPacket(new GeoPoint(0,1000.00,200), new GeoPoint(2234.1,7235,100), "testCar");
    packetStore.add(packet);
    packetList.add(packet);
    packet = new TraffoPacket(
        new GeoPoint(54345.543,2212,5), new GeoPoint(4323543.2,54543.1,100), "testBus");
    packetStore.add(packet);
    packetList.add(packet);
    assertTrue("equal contents", equalContents(packetStore, packetList));
    packetStore = null;
    packetStore = new FilePacketStore(packetFilePath);
    assertTrue("contents equal after re-creation", equalContents(packetStore, packetList));
    packetStore.clear();
    packetList.clear();
    assertTrue("contents equal after clear", equalContents(packetStore, packetList));
    packetStore = null;
    packetStore = new FilePacketStore(packetFilePath);
    assertTrue("contents equal after clear, re-creation", equalContents(packetStore, packetList));
    packetFile.delete();
    packetFileParent.delete();
  }
  
}